//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: demoim.c 757 2007-05-10 08:19:31Z roger $
//

#include <unihan_im.h>
#include <unihan_im_keycodes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef struct {
	char preedit[11];
	int len;
	int pos;
} DemoIMSessionData;

int unihan_im_module_init(void);
void unihan_im_module_done(void);
int unihan_im_module_get_info(UnihanIMModuleArgList *args);

static int demoim_init(UnihanIM *uim);
static int demoim_done(UnihanIM *uim);
static int demoim_create_session(UnihanIM *uim);
static int demoim_destroy_session(UnihanIM *uim);
static int demoim_handle_event(UnihanIM *uim, IMEvent *ev);
static int handle_key_event(UnihanIM *uim, IMKeyEvent *ev);
static int handle_focus_event(UnihanIM *uim, IMFocusEvent *ev);
static int handle_config_change_event(UnihanIM *uim, IMConfigChangeEvent *ev);
static int handle_switch_event(UnihanIM *uim, IMSwitchEvent *ev);

int
unihan_im_module_init(void)
{
	fprintf(stderr, "demoim: unihan_im_module_init()\n");

	/* The input module can do some initialization here */
	
	return TRUE;
}


void
unihan_im_module_done(void)
{
	fprintf(stderr, "demoim: unihan_im_module_done()\n");

	/* The input module can do some finalization here */
	
	return;
}


int
unihan_im_module_get_info(UnihanIMModuleArgList *args)
{
	IMMethods *imm = NULL;
	IMInfo *iminfo = NULL;

	fprintf(stderr, "demoim: unihan_im_module_get_info()\n");
	
	if (!args) return FALSE;
	while (args->id) {
		switch (args->id) {
			case UNIHAN_IM_API_VERSION:
				/* Unihan only supports API version 1.0 now */
				args->value = (void*)0x00010000;
				break;
			case UNIHAN_IM_MODULE_ID:
				/* The ID of the input module */
				args->value = strdup("demoim");
				break;
			case UNIHAN_IM_MODULE_NAME:
				/* Human readable name of the input module */
				args->value = strdup("test IM module 'demoim'");
				break;
			case UNIHAN_IM_MODULE_VERSION:
				/* Version of the input module */
				args->value = strdup("1.0");
				break;
			case UNIHAN_IM_MODULE_IM_LIST:
				/* List of input methods in this input
				** module */
				imm = (IMMethods *)malloc(sizeof(IMMethods));
				iminfo = (IMInfo *)malloc(sizeof(IMInfo) * 2);
				memset(imm, 0, sizeof(IMMethods));
				memset(iminfo, 0, sizeof(IMInfo));

				/* define callback functions */
				imm->init = demoim_init;
				imm->done = demoim_done;
				imm->create_session = demoim_create_session;
				imm->destroy_session = demoim_destroy_session;
				imm->handle_event = demoim_handle_event;
				/* other info of this input method */
				iminfo->id = strdup("demoim_im");
				iminfo->name = strdup("test IM 'demoim'");
				iminfo->version = strdup("1.0");
				iminfo->imUserData = NULL;
				iminfo->methodTable = imm;
				/* there is only 1 input method in this
				** module, so next is NULL */
				iminfo->next = NULL;

				args->value = iminfo;
				break;
		}
		++args;
	}

	return TRUE;
}


static int
demoim_init(UnihanIM *uim)
{
	char *locale = NULL;
	int err;
	
	fprintf(stderr, "demoim: demoim_init()\n");
	uim->desktopUserData = NULL;

	err = uim->m->locale_get(uim, &locale);
	if (err == 0)
		fprintf(stderr, "demoim: user's locale is %s\n", locale);

	return TRUE;
}


static int
demoim_done(UnihanIM *uim)
{
	fprintf(stderr, "demoim: demoim_done()\n");
	return TRUE;
}


static int
demoim_create_session(UnihanIM *uim)
{
	fprintf(stderr, "demoim: demoim_create_session()\n");
	uim->sessionUserData = malloc(sizeof(DemoIMSessionData));
	memset(uim->sessionUserData, 0, sizeof(DemoIMSessionData));
	return TRUE;
}


static int
demoim_destroy_session(UnihanIM *uim)
{
	fprintf(stderr, "demoim: demoim_destroy_session()\n");
	free(uim->sessionUserData);
	return TRUE;
}


static int
demoim_handle_event(UnihanIM *uim, IMEvent *ev)
{
	fprintf(stderr, "demoim: demoim_handle_event()\n");

	switch (ev->type) {
		case IM_KEY:
			return handle_key_event(uim, (IMKeyEvent*)ev);
		case IM_FOCUS:
			return handle_focus_event(uim, (IMFocusEvent*)ev);
		case IM_CONFIG_CHANGE:
			return handle_config_change_event(uim, (IMConfigChangeEvent*)ev);
		case IM_SWITCH:
			return handle_switch_event(uim, (IMSwitchEvent*)ev);
		case IM_NOTHING:
		default:
			break;
	}

	return FALSE;
}


static int
handle_key_event(UnihanIM *uim, IMKeyEvent *ev)
{
	int err;
	DemoIMSessionData *s = (DemoIMSessionData *)uim->sessionUserData;

	if (ev->modifier == 0 && ev->keyChar >= 'a' && ev->keyChar <= 'z') {
		if (s->len < 10) {
			s->preedit[s->len++] = ev->keyChar;
			uim->m->preedit_draw(uim, s->preedit, NULL);
		}
		return TRUE;
	} else if (ev->modifier == 0 && ev->keyCode == IM_VK_ENTER) {
		if (s->len == 0)
			return FALSE;

		if (!strcmp("demoim", s->preedit)) {
			char *str = strdup("仆街");
			err = uim->m->commit_string(uim, str);
			if (err != 0) {
				/* some error occurred */
			}
			free(str);
			s->len = 0;
			memset(s->preedit, 0, 11);
			uim->m->preedit_erase(uim);
		}
		return TRUE;
	} else if (ev->modifier == 0 && ev->keyCode == IM_VK_ESCAPE) {
		if (s->len == 0)
			return FALSE;

		s->len = 0;
		memset(s->preedit, 0, 11);
		uim->m->preedit_erase(uim);
		return TRUE;
	} else if (ev->modifier == 0 && ev->keyCode == IM_VK_BACK_SPACE) {
		if (s->len == 0)
			return FALSE;

		--s->len;
		s->preedit[s->len] = '\0';
		uim->m->preedit_draw(uim, s->preedit, NULL);
		return TRUE;
	}

	return FALSE;
}


static int
handle_focus_event(UnihanIM *uim, IMFocusEvent *ev)
{
	if (ev->focused == TRUE) {
		/* the input area has received focus */
	} else {
		/* the input area lost focus */
	}
}


static int
handle_config_change_event(UnihanIM *uim, IMConfigChangeEvent *ev)
{
	fprintf(stderr, "demoim: config key %s has changed\n", ev->key);
}


static int
handle_switch_event(UnihanIM *uim, IMSwitchEvent *ev)
{
	if (ev->on == TRUE) {
		/* the user has switched on this input method */
	} else {
		/* the user has switched off this input method */
	}
}

// vi:ts=4:nowrap:cin:expandtab
